﻿using System.Collections.Generic;
using System.Globalization;
using System.Text;

namespace App_Code
{
    /// <summary>
    /// Summary description for MapScriptBuilder
    /// </summary>
    public class MapScriptBuilder
    {
        static readonly Dictionary<string, PlaceCoordinate> _places = new Dictionary<string, PlaceCoordinate>();

        /// <summary>
        /// handles the complexity of building javascript and inserting it into the response stream
        /// </summary>
        static MapScriptBuilder()
        {
            _places.Add("laos", new PlaceCoordinate(17.8, 103.7, 7));
            _places.Add("northernlaos", new PlaceCoordinate(19.6, 102.4, 8));
            _places.Add("centrallaos", new PlaceCoordinate(18.3, 103, 8));
            _places.Add("southernlaos", new PlaceCoordinate(16.4, 105.6, 8));
            _places.Add("luangprabang", new PlaceCoordinate(19.88, 102.141, 15));
            _places.Add("vientianne", new PlaceCoordinate(17.96, 102.61, 13));
            _places.Add("vangvieng", new PlaceCoordinate(18.91, 102.447, 15));
            _places.Add("xamneua", new PlaceCoordinate(20.409, 104.048, 15));
            _places.Add("houeixai", new PlaceCoordinate(20.263, 100.42, 14));
            _places.Add("muangsing", new PlaceCoordinate(21.191, 101.148, 15));
            _places.Add("udomxai", new PlaceCoordinate(20.68, 101.98, 15));
            _places.Add("nongkhiaw", new PlaceCoordinate(20.565, 102.617, 15));
            _places.Add("phonsavanh", new PlaceCoordinate(19.449, 103.185, 13));
            _places.Add("luangnamtha", new PlaceCoordinate(21.0, 101.407, 15));
            _places.Add("savannakhet", new PlaceCoordinate(16.564,104.75, 15));
            _places.Add("thakhek", new PlaceCoordinate(17.398, 104.812, 15));
            _places.Add("pakse", new PlaceCoordinate(15.11, 105.8, 15));
            _places.Add("attapeu", new PlaceCoordinate(14.81, 106.82, 15));
        }

        private static string BuildMapOptionStringByPlaceName(string queryString, string path, string layer, string busStopID)
        {
            // HTTP puts '+' in for spaces

            string key = queryString.ToLower().Replace("+", "").Replace(" ", "");

            PlaceCoordinate placeCoordinate;

            if (busStopID != null)
            {
                var btc = new BustimesController();
                placeCoordinate = btc.GetPlaceCoordinate(busStopID);

                if (placeCoordinate != null)
                {
                    return BuildMapOptionString(placeCoordinate, path, layer);
                }
            }

            if (_places.TryGetValue(key, out placeCoordinate))
            {
                return BuildMapOptionString(placeCoordinate, path, layer);
            }

            return BuildMapOptionString(new PlaceCoordinate(17.8, 103.7, 7), path, layer);
        }

        /*    
     
    "var latlng = new google.maps.LatLng(52.04, -0.75);"+
    "myOptions = {zoom: 12, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };" 
     
   * */

        private static string BuildMapOptionString(PlaceCoordinate place, string path, string layer)
        {
            var sb = new StringBuilder();
            sb.Append(BuildMapZoomString(place));
            sb.Append(BuildMapTrafficOption(path, layer));
            return sb.ToString();
        }

        public static string BuildMapContentMvc(string placeName, string heading, string layer, string busStopID)
        {
            // http://code.google.com/apis/maps/documentation/javascript/controls.html

            string injectStartUp = "<script type='text/javascript'>\r\n" +
                "var kickoff = function () {\r\n" +
                "  var map;\r\n" +
                "  function initialize() {\r\n" +
                    BuildMapOptionStringByPlaceName(placeName, "../", layer, busStopID) +
                "    var map = new google.maps.Map(document.getElementById(\"map_canvas\"), myOptions);" +

                "map.overlayMapTypes.insertAt(0, trafficMapType);\r\n" + // new 
                "google.maps.event.addListener(map, 'click', showArrays);\r\n" +

                "\r\n" +
                "var lyrsT = new google.maps.ImageMapType({\r\n" +
                "  getTileUrl: function(ll, z) {\r\n" +
                "    var X = ll.x % (1 << z);  // wrap\r\n" +
                "    return \"../maptile.aspx?x=\"\r\n" +       // main page
                "    +X + \"&y=\" + ll.y + \"&zoom=\" + z + \"&layer=background\";\r\n" +
                "  },\r\n" +

                "\r\n" +
                "  tileSize: new google.maps.Size(256, 256),\r\n" +
                "  isPng: true,\r\n" +
                "  maxZoom: 21,\r\n" +
                "  minZoom: 6,\r\n" +

                "  name: \"Traveller\",\r\n" +
                "  alt: \"Our custom mapping data\"\r\n" +
                "});\r\n" +
                "\r\n" +
                "map.mapTypes.set('lyrsTMain', lyrsT);\r\n" +
                "map.setMapTypeId(google.maps.MapTypeId.ROADMAP);\r\n" +
                "\r\n" +
                "};\r\n" +
                "  initialize();\r\n" +

                "  document.getElementById(\"map_canvas\").style.width = fnIsLinear() ? \"80%\" : \"99%\" ;\r\n" +
                "  document.getElementById(\"map_canvas_parent\").style.paddingLeft = fnIsLinear() ? \"10%\" : \"0%\" ;\r\n" +

                "  function showArrays(event) {\r\n" +
                "    alert('Lat: ' + event.latLng.lat() + ' Lng: ' + event.latLng.lng());\r\n" +
                "  };\r\n" +
                "};\r\n" +

                "startUpThingsToDo.push(kickoff);\r\n" +
                "</script>";

            string contentUsed = injectStartUp + "<div id=\"divmid\" style=\"width: 100%; height: 1000px;\"  >" +
                                "<div id=\"map_canvas_parent\"class=\"divinner\"  style=\"width: 100%; height: 100%; \"  >  <h1>" + heading + " - " + placeName + "</h1><br/>";
            contentUsed += "<div id=\"map_canvas\"  style=\" height: 100%; \"></div>";
            contentUsed += "</div></div>";
            return contentUsed;
        }


        public static string BuildMapContent(string placeName, string heading)
        {
            if (placeName.Length == 0)
                placeName = "Laos";

            // http://code.google.com/apis/maps/documentation/javascript/controls.html

            string injectStartUp = "<script type='text/javascript'>\r\n" +
                "var kickoff = function () {\r\n" +
                "  var map;\r\n" +
                "  function initialize() {\r\n" +
                    BuildMapOptionStringByPlaceName(placeName, "", "border", null) +
                "    var map = new google.maps.Map(document.getElementById(\"map_canvas\"), myOptions);" +

                "map.overlayMapTypes.insertAt(0, trafficMapType);\r\n" + // new 
                "google.maps.event.addListener(map, 'click', showArrays);\r\n" +

                "\r\n" +
                "var lyrsT = new google.maps.ImageMapType({\r\n" +
                "  getTileUrl: function(ll, z) {\r\n" +
                "    var X = ll.x % (1 << z);  // wrap\r\n" +
                "    return \"maptile.aspx?x=\"\r\n" +       // main page
                "    +X + \"&y=\" + ll.y + \"&zoom=\" + z + \"&layer=background\";\r\n" +
                "  },\r\n" +

                "\r\n" +
                "  tileSize: new google.maps.Size(256, 256),\r\n" +
                "  isPng: true,\r\n" +
                "  maxZoom: 21,\r\n" +
                "  minZoom: 6,\r\n" +

                "  name: \"Traveller\",\r\n" +
                "  alt: \"Our custom mapping data\"\r\n" +
                "});\r\n" +
                "\r\n" +
                "map.mapTypes.set('lyrsTMain', lyrsT);\r\n" +
                "map.setMapTypeId(google.maps.MapTypeId.ROADMAP);\r\n" +
                "\r\n" +
                "};\r\n" +
                "  initialize();\r\n" +

                "  document.getElementById(\"map_canvas\").style.width = fnIsLinear() ? \"80%\" : \"99%\" ;\r\n" +
                "  document.getElementById(\"map_canvas_parent\").style.paddingLeft = fnIsLinear() ? \"10%\" : \"0%\" ;\r\n" +

                "  function showArrays(event) {\r\n" +
                "    alert('Lat: ' + event.latLng.lat() + ' Lng: ' + event.latLng.lng());\r\n" +
                "  };\r\n" +
                "};\r\n" +

                "startUpThingsToDo.push(kickoff);\r\n" +
                "</script>";

            string contentUsed = injectStartUp + "<div id=\"divmid\" style=\"width: 100%; height: 1000px;\"  >" +
                                "<div id=\"map_canvas_parent\"class=\"divinner\"  style=\"width: 100%; height: 100%; \"  >  <h1>" + heading + " - " + placeName + "</h1><br/>";
            contentUsed += "<div id=\"map_canvas\"  style=\" height: 100%; \"></div>";
            contentUsed += "</div></div>";
            return contentUsed;
        }

        private static string BuildMapZoomString(PlaceCoordinate place)
        {
            const string scale = "  scaleControl: true,\r\n" +
                                 "  scaleControlOptions: {\r\n" +
                                 "  position: google.maps.ControlPosition.TOP_CENTER},\r\n";

            var sb = new StringBuilder();
            sb.Append("var latlng = new google.maps.LatLng(");
            sb.Append(string.Format(CultureInfo.InvariantCulture, "{0:0.##}, {1:0.##}", place._latitude, place._longitude));
            sb.Append(");\r\n" + "myOptions = {zoom:");
            sb.Append(place._zoom);
            
            sb.Append(", mapTypeControl: true"); // new 23/9/11
            sb.Append(", mapTypeControlOptions: { mapTypeIds: [" +
                "'lyrsTMain', google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.HYBRID, google.maps.MapTypeId.TERRAIN" +
                "], style: google.maps.MapTypeControlStyle.DROPDOWN_MENU }");

            sb.Append(", backgroundColor: \"#ffffff\"," + scale + " center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP };\r\n\r\n");
            return sb.ToString();
        }

        //http://code.google.com/apis/maps/documentation/javascript/maptypes.html
        private static string BuildMapTrafficOption(string path, string layer)
        {
            var sb = new StringBuilder();
            sb.Append("var trafficOptions = {\r\n");
            sb.Append(" getTileUrl: function(coord, zoom) {\r\n");
            sb.Append("return \""+path + "maptile.aspx?\" + \r\n"); // traffic overlay
            sb.Append("\"zoom=\" + zoom + \"&x=\" + coord.x + \"&y=\" + coord.y + \"&layer="+layer+"\";\r\n");
            sb.Append(" },\r\n");
            sb.Append(" tileSize: new google.maps.Size(256, 256),\r\n");
            sb.Append(" isPng: true};\r\n\r\n");
            sb.Append("var trafficMapType = new google.maps.ImageMapType(trafficOptions);\r\n");
            return sb.ToString();
        }
    }
}